package uml.FileIO;

import java.util.ArrayList;
import java.util.Scanner;

public class FileScanner
{
	private ArrayList<ArrayList<ScanLine>> m_objects;

	/**
	 * Default Constructor for FileScanner. Initializes m_objects.
	 */
	
	private FileScanner ()
	{
		m_objects = new ArrayList<ArrayList<ScanLine>> ();
	}

	/**
	 * Tokenizes incoming file. Adds all tokens to token ArrayList
	 * @param scan
	 * @return ArrayList of tokens
	 */
	
	public static ArrayList<ArrayList<ScanLine>> tokenize (Scanner scan)
	{
		FileScanner scanner = new FileScanner();
		scanner.scanFile (scan);
		ArrayList<ArrayList<ScanLine>> tokens = new ArrayList<ArrayList<ScanLine>> (scanner.m_objects);
		scanner.m_objects.clear ();
		return tokens;
	}

	/**
	 * Scan through a file and adds till the end is reached. Adds scanned lines as blocks to m_objects.
	 * @param scanner
	 */
	
	public void scanFile (Scanner scanner)
	{
		while (scanner.hasNext ())//till end of file
		{
			for (ScanLine line = scanLine (scanner); line.m_lexeme != FileToken.BEGIN; line = scanLine (scanner))
				;//throw these lines out
			m_objects.add (scanBlock (scanner));//entered a block
		}
	}

	/**
	 * Returns scanned lines as a block.
	 * @param scanner
	 * @return
	 */
	
	public ArrayList<ScanLine> scanBlock (Scanner scanner)
	{
		ArrayList<ScanLine> block = new ArrayList<ScanLine> ();
		for (ScanLine line = scanLine (scanner); line.m_lexeme != FileToken.END; line = scanLine (scanner))
			block.add (line);
		return block;
	}

	/**
	 * Reads through scanner and until there are no lines left.
	 * @param scanner
	 * @return
	 */
	public ScanLine scanLine (Scanner scanner)
	{
		while (scanner.hasNext ())
		{
			FileToken token = FileToken.matchToken (scanner.next ());
			if (token != null)
				return new ScanLine (token, scanner.nextLine ());
		}
		return null;

	}

	/**
	 * A ScanLine object is a FileToken and String
	 * @author Dizzy
	 *
	 */
	
	public class ScanLine
	{
		public FileToken m_lexeme;
		public String m_params;

		/** 
		 * Default constructor for ScanLine
		 * @param token
		 * @param parameters
		 */
		
		ScanLine (FileToken token, String parameters)
		{
			m_lexeme = token;
			m_params = parameters;
		}
	}
}
